package com.zhexiao.convert.component;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;

/**
 * 读取文件数据，解析json文件
 *
 * @author zhe.xiao
 * @date 2020/09/11
 * @description 上传图片保存到本地
 */
@Component
public class ReadFile {
    private static final Logger log = LoggerFactory.getLogger(ReadFile.class);


    /**
     * 读取文件
     * 使用 Charset + CharsetDecoder 解决了中文乱码问题
     *
     * @param fis
     * @return
     */
    public String read(FileInputStream fis) {
        StringBuilder stringBuilder = new StringBuilder();

        //解决中文乱码问题
        Charset charset = StandardCharsets.UTF_8;
        CharsetDecoder decoder = charset.newDecoder();
        char[] charCache = null;

        try (
                FileChannel fisChannel = fis.getChannel()
        ) {
            //分配缓冲区、分配字符缓冲区解决中文乱码
            ByteBuffer byteBuffer = ByteBuffer.allocate(10240);
            CharBuffer charBuffer = CharBuffer.allocate(10240);

            //读取数据
            while (fisChannel.read(byteBuffer) != -1) {
                //上面把数据写入到了buffer，所以可知上面的buffer是写模式，调用flip把buffer切换到读模式，读取数据
                byteBuffer.flip();

                //把字节buffer解码到字符buffer
                decoder.decode(byteBuffer, charBuffer, true);

                //字符buffer切换到读模式
                charBuffer.flip();

                //存储字符
                charCache = new char[charBuffer.length()];
                while (charBuffer.hasRemaining()) {
                    charBuffer.get(charCache);
                }
                stringBuilder.append(charCache);

                //读完了buffer，清空buffer
                charBuffer.clear();
                byteBuffer.clear();
            }
        } catch (Exception e) {
            log.info("读取文件异常,e={}", e.getMessage());
            return null;
        }

        return stringBuilder.toString();
    }

    /**
     * 解析文件
     *
     * @param file
     * @return
     */
    public String read(MultipartFile file) {
        try (
                FileInputStream fileInputStream = (FileInputStream) file.getInputStream();
        ) {
            return this.read(fileInputStream);
        } catch (Exception e) {
            log.info("读取文件异常,file={}, e={}", file, e.getMessage());
            return null;
        }
    }

    /**
     * 解析文件
     *
     * @param filepath
     * @return
     */
    public String read(String filepath) {
        try (
                FileInputStream fileInputStream = new FileInputStream(filepath);
        ) {
            return this.read(fileInputStream);
        } catch (Exception e) {
            log.info("读取文件异常,filepath={}, e={}", filepath, e.getMessage());
            return null;
        }
    }
}